package com.ruyuan.little.project.rocketmq.api.order.listener;

import com.alibaba.fastjson.JSON;
import com.ruyuan.little.project.rocketmq.api.message.dto.OrderInfo;
import com.ruyuan.little.project.rocketmq.api.order.dto.OrderInfoDTO;
import com.ruyuan.little.project.rocketmq.api.order.enums.OrderStatusEnum;
import com.ruyuan.little.project.rocketmq.api.order.service.OrderEventInformManager;
import com.ruyuan.little.project.rocketmq.api.order.service.OrderService;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 退房订单处理器
 * @author 强军
 */
@Component
public class FinishedOrderTransactionListener implements TransactionListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(FinishedOrderTransactionListener.class);

    @Resource
    private OrderService orderService;
    @Resource
    private OrderEventInformManager orderEventInformManager;

    /**
     * 执行本地事务：
     * 这里就是更新订单的状态：完成（退房）
     *
     * @param message
     * @param o
     * @return LocalTransactionState
     */
    @Override
    public LocalTransactionState executeLocalTransaction(Message message, Object arg) {

        String body = new String(message.getBody(), StandardCharsets.UTF_8);
        OrderInfoDTO orderInfoDTO = JSON.parseObject(body, OrderInfoDTO.class);
        String orderNo = orderInfoDTO.getOrderNo();
        String phoneNumber = orderInfoDTO.getPhoneNumber();
        LOGGER.info("callback execute finished order local transaction orderNo:{}", orderNo);

        try {
            orderService.updateOrderStatus(orderNo, OrderStatusEnum.FINISHED, phoneNumber);
            orderEventInformManager.informOrderFinishEvent(orderInfoDTO);
            LOGGER.info("finished order local transaction execute success commit orderNo:{}", orderNo);
            return LocalTransactionState.COMMIT_MESSAGE;
        } catch (Exception e) {
            LOGGER.info("finished order local transaction execute success fail rollback orderNo:{}", orderNo);
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
    }

    /**
     * 检查本地事务执行结果
     * 用来方式mq没有及时收到本地事务的执行结果
     *
     * @param messageExt
     * @return
     */
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {

        String body = new String(messageExt.getBody(), StandardCharsets.UTF_8);
        OrderInfoDTO orderInfoDTO = JSON.parseObject(body, OrderInfoDTO.class);
        String orderNo = orderInfoDTO.getOrderNo();
        String phoneNumber = orderInfoDTO.getPhoneNumber();
        LOGGER.info("callback check finished order local transaction orderNo:{}", orderNo);

        try {
            Integer orderStatus = orderService.getOrderStatus(orderNo, phoneNumber);
            if (Objects.equals(orderStatus, OrderStatusEnum.FINISHED.getStatus())) {
                LOGGER.info("finished order local transaction check result success commit orderNo:{}", orderNo);
                return LocalTransactionState.COMMIT_MESSAGE;
            } else {
                LOGGER.info("finished order local transaction check result fail rollback orderNo:{}", orderNo);
                return LocalTransactionState.ROLLBACK_MESSAGE;
            }
        } catch (Exception e) {
            // 查询订单状态失败
            LOGGER.info("finished order local transaction check result fail rollback orderNo:{}", orderNo);
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
    }
}
